package com.dhecp.project.system.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dhecp.common.config.Global;
import com.dhecp.common.utils.security.RsaUtils;
import com.dhecp.framework.shiro.realm.CustomUsernamePasswordToken;
import com.dhecp.framework.shiro.session.OnlineSession;
import com.dhecp.framework.shiro.session.OnlineSessionDAO;
import com.dhecp.project.system.domain.SysHardWareRegisterInfo;
import com.dhecp.project.system.service.SysHardWareRegisterInfoService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.dhecp.common.core.controller.BaseController;
import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.common.utils.ServletUtils;
import com.dhecp.common.utils.StringUtils;
import com.dhecp.framework.util.ShiroUtils;
import com.dhecp.project.system.domain.SysSetting;
import com.dhecp.project.system.domain.SysUserInfo;
import com.dhecp.project.system.service.SysDictionaryForModuleService;
import com.dhecp.project.system.service.SysSettingService;
import com.dhecp.project.system.service.SysUserInfoService;

/**
 * 登录验证
 */
@Controller
public class SysLoginController extends BaseController{
    @Autowired
    private SysSettingService settingService;

    @Autowired
    private SysUserInfoService userInfoService;

    @Autowired
    private SysDictionaryForModuleService dictionaryForModuleService;

    @Autowired
    private SysHardWareRegisterInfoService sysHardWareRegisterInfoService;

    @Autowired
    private OnlineSessionDAO onlineSessionDAO;

    @GetMapping("/login")
    public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap)
    {
        // 如果是Ajax请求，返回Json字符串。
        if (ServletUtils.isAjaxRequest(request))
        {
            return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
        }
        mmap.put("projectName", Global.getName());
        String pcId = request.getParameter("pcId");
        String rememberUser = "";
        if(!StringUtils.isEmpty(pcId)){
            SysHardWareRegisterInfo sysHardWareRegisterInfo = sysHardWareRegisterInfoService.findSysHardWareRegisterInfoByHardInfo(pcId);
            if(sysHardWareRegisterInfo != null){
                rememberUser = sysHardWareRegisterInfo.getRememberUser();
            }
        }
        mmap.put("rememberUser", rememberUser);
        mmap.put("pcId", StringUtils.isEmpty(pcId)? "":pcId);
        return "login";
    }

    @PostMapping("/login")
    @ResponseBody
    public AjaxResult ajaxLogin(HttpServletRequest request,String username, String password,String mandator, Boolean rememberMe){
        String userAgent = request.getHeader("User-Agent");
        String pcId = request.getParameter("pcId");
        String originalPassword = "";//加密前的密码
        try {
            originalPassword = RsaUtils.decryptByPrivateKey(password);
        } catch (Exception e) {
            return error("请传输加密的密码！");
        }
        CustomUsernamePasswordToken token = new CustomUsernamePasswordToken(username, originalPassword, rememberMe, userAgent, false);
        Subject subject = SecurityUtils.getSubject();
        try
        {
            //先判断sessionId是否有相同数据但登录用户名不一致
            Session oldSession = onlineSessionDAO.readSession(subject.getSession().getId());
            if (oldSession != null && oldSession instanceof OnlineSession) {
                OnlineSession onlineSession = (OnlineSession) oldSession;
                // String onlineLoginName  = onlineSession.getLoginName();
                // if (!StringUtils.isEmpty(onlineLoginName) && !onlineLoginName.contains(username)){
                if (!StringUtils.isEmpty(onlineSession.getUserName()) && !onlineSession.getLoginName().contains(username)){
                    Map<String, Object> resParams = new HashMap<String, Object>();
                    resParams.put("repeatLogin", "1");
                    resParams.put("loginName", onlineSession.getLoginName());
                    resParams.put("userName", onlineSession.getUserName());
                    resParams.put("deptName", onlineSession.getDeptName());
                    resParams.put("lastAccessTime", onlineSession.getLastAccessTime());
                    return AjaxResult.error("此浏览器已有用户登录，请先退出之前登录用户【" + onlineSession.getLoginName() + "/" + onlineSession.getUserName() +"】，再登录！", resParams);
                }
            }
            subject.login(token);
            Session session = subject.getSession();
            //添加H5部署平台
            session.setAttribute("h5DeployType", Global.getH5DeployType());
            //添加系统设置信息
            SysSetting systemSet = settingService.querySetting();
            session.setAttribute("systemSet", systemSet); 
            
            //添加需要身份验证的功能
            Map<String, Object> params = new HashMap<String, Object>();
            Map<String, String> authenticationModuleMap = dictionaryForModuleService.queryAuthenticationModule(params);
            session.setAttribute("authenticationModuleMap", authenticationModuleMap);
            
            //添加委托（被代理）用户
            if (mandator == null || "".equals(mandator) || username.equals(mandator)){
            	session.setAttribute("mandatorUser",ShiroUtils.getSysUser());// 非代理情况，委托人为自己
            }else{
                SysUserInfo mandatorUser = userInfoService.queryByUserId(mandator);
                if (mandatorUser == null){
                	return error("委托（被代理）用户不存在！");
                }
                if (mandatorUser.getDisabled()){
                	return error("委托（被代理）用户已被禁用！");
                }
                session.setAttribute("mandatorUser",mandatorUser);
            }
            
            //拓展用户登录验证（核心验证在SysLoginService类login方法中进行）
            Map<String, Object> exceptions = new HashMap<String, Object>();
            exceptions.put("loginUser", username);	//当前登录用户
            exceptions.put("mandator", mandator);	//委托（被代理）用户
            exceptions.put("serviceTime", new Date());	//中间层服务器时间
            String exceptionmsg = userInfoService.queryUserLoginException(exceptions);
            if (!"".equals(exceptionmsg)){
                return error(exceptionmsg);
            }
            //有选择中记住用户，更新已注册信息表信息
            if(rememberMe == true && !StringUtils.isEmpty(pcId)) {
                try {
                    sysHardWareRegisterInfoService.updateSysHardWareRegisterInfoByHardInfo(pcId, username);
                } catch (Exception ex1) {
                }
            }
            String userId = ShiroUtils.getUserId();
            String userName = ShiroUtils.getUserId().equals(ShiroUtils.getMandatorId()) ? ShiroUtils.getUserName() : ShiroUtils.getUserName() + "[代理:" + ShiroUtils.getMandatorName() + "]";
            Integer userLevel = ShiroUtils.getSysUser().getUserLevel();
            session.setAttribute("userId", userId); //添加当前登录用户编号
            session.setAttribute("userName", userName); //添加当前登录用户名称
            session.setAttribute("userLevel", userLevel); //添加当前登录用户级别
            return success();
        }
        catch (AuthenticationException e)
        {
            String msg = "用户或密码错误";
            if (StringUtils.isNotEmpty(e.getMessage()))
            {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }

    //CS登录硬件验证
    @PostMapping("/cshardware")
    @ResponseBody
    public AjaxResult csHardware(String hostip, String hardinfo,String hostname){
        if(StringUtils.isEmpty(hostip) || StringUtils.isEmpty(hardinfo) || StringUtils.isEmpty(hostname)){
            return error("电脑验证参数中有一项为空，验证失败！");
        }
        if(sysHardWareRegisterInfoService.querySysHardWareRegisterInfoIsExistHardInfo(hardinfo) == false){
            SysHardWareRegisterInfo model = new SysHardWareRegisterInfo();
            model.setHostIP(hostip);
            model.setHardInfo(hardinfo);
            model.setHostName(hostname);
            sysHardWareRegisterInfoService.insertSysHardWareUnRegisterInfo(model);
            return error("电脑未授权注册，验证失败！");
        }
        return success("验证成功！");
    }

    @GetMapping("/unauth")
    public String unauth()
    {
        return "error/unauth";
    }
}
